home *** CD-ROM | disk | FTP | other *** search
/ Chip 2001 November / Chip Kasım 2001.iso / prog / share / 3dprod / setup.exe / FastHtmlGen / form.js < prev    next >
Encoding:
Text File  |  2001-08-10  |  40.1 KB  |  1,427 lines

  1.  
  2. // Exports:
  3. // - init()
  4. // - reset(which)
  5. // - process()
  6. // - Arthur
  7. // - doSkip()
  8. // - zoomwin()
  9. // - toggleLoop()
  10. // - setUrlVal()
  11. // - setDimVal()
  12. // - setHexVal()
  13. //
  14. // Callbacks:
  15. // - selectObject() (onmousedown)
  16. // - dragObject() (onmousemove)
  17. // - freeObject() (onmouseup)
  18.  
  19. // Platform detection ------------------------------------------------------ //
  20.  
  21. ns4 = (document.layers) ? true : false;
  22. // ie4 = (document.all) ? true : false;
  23.  
  24. // called once page has loaded
  25. function init()
  26. {
  27.     // Constants, Aliases -------------------------------------------------- //
  28.  
  29.     initFromSubs(); // get substitution globals
  30.  
  31.     // ranges //
  32.     SRANGE = 255;
  33.  
  34.     S_HMIN = 56;
  35.     S_HMAX = S_HMIN + SRANGE;
  36.  
  37.     CP_MAX = 2;
  38.     CP_MIN = -CP_MAX;
  39.     CP_RANGE = CP_MAX - CP_MIN;
  40.  
  41.     CA_MAX = 180;
  42.     CA_MIN = -CA_MAX;
  43.     CA_RANGE = CA_MAX - CA_MIN;
  44.         
  45.     LP_MAX = 20;
  46.     LP_MIN = -LP_MAX;
  47.     LP_RANGE = LP_MAX - LP_MIN;
  48.  
  49.     WIN_MAX = 999; // 3 digits
  50.     WIN_MIN = 1;
  51.  
  52.     // other constants
  53.     WIN_DFLT = 200;
  54.     var VIEW_SITE = 'http://www.famous3d.com/viewer/'
  55.     LOGO_IMG_TAG = '<img src="' + VIEW_SITE +
  56.         'images/viewer_logo.gif" width=90 height=90 alt="Logo">';
  57.     INSTALL_IMG_TAG = '<img src="' + VIEW_SITE +
  58.         'images/installing.gif" width=150 height=72 alt="Installing">';
  59.     ABOUT_LINK =  VIEW_SITE + 'about.html';
  60.     IE_LINK = 'http://www.microsoft.com/ie/';
  61.     NS_LINK = 'http://home.netscape.com/';
  62.  
  63.     SKIP_BUT = ROOTDIR + '/images/skip.gif';
  64.     SKIP_BUT_GS = ROOTDIR + '/images/skipgs.gif';
  65.     
  66.     BG_URL = '';
  67.  
  68.     DELAY_TM = 100;
  69.  
  70.     // also seen: size=1 color="#000000"
  71.     FONT_VALS = 'face="verdana, san-serif" size=2';
  72.     LPXY_DFLT = 1;
  73.     LPZ_DFLT = 10;
  74.  
  75.     // docwrite
  76.     CDW_OPEN = "document.write('";
  77.     CDW_CLOSE = "\\n');\n";
  78.  
  79.     CDoc = parent.frames["code"].document;
  80.     HDoc = parent.frames["head"].document;
  81.     DDoc = parent.frames["code"].document; // was "dirs"
  82.     
  83.     // Globals ------------------------------------------------------------- //
  84.  
  85.     SelectedSlide = null;
  86.     Idle = false;
  87.     PrevHelp = null;
  88.     Arthur = null;
  89.     NeedArthurUpdate = false;
  90.  
  91.     // Checks -------------------------------------------------------------- //
  92.  
  93.     // check for Java and CSS (cf no Javascript warning in dirs.html)
  94.     if (!checkJava())
  95.         reportErr("WARNING: The famous3D Code Generator requires a " +
  96.                   "Java-enabled browser.  Either your browser doesn't " +
  97.                   "support Java, or you have disabled it.", 'No Java');
  98.     else if (!checkCss())
  99.         reportErr("WARNING: The famous3D Code Generator requires a " +
  100.                   "CSS-enabled browser.  Either your browser doesn't " +
  101.                   "support CSS, or you have disabled CSS.", 'No CSS');
  102.  
  103.     // Setup --------------------------------------------------------------- //
  104.  
  105.     // checkIdle vars //
  106.     if (ns4)
  107.     {
  108.         loopcell = document.optionssection.document.options.loopcell;
  109.         lockcell = document.optionssection.document.options.lockcell;
  110.         skipButton = document.panel.document.skip;
  111.     }
  112.     else
  113.     {
  114.         loopcell = options.loopcell;
  115.         lockcell = options.lockcell;
  116.         skipButton = skip;
  117.     }
  118.  
  119.     // Setup plugin frame //
  120.     // do this ASAP -- cf Arthur global (aInit()), below.
  121.     // needs checkIdle() vars initted
  122.     makeArthur();
  123.  
  124.     // Callbacks //
  125.     document.onmousedown = selectObject;
  126.     // other callbacks now done only if selected
  127.  
  128.     if (ns4)
  129.         document.captureEvents
  130.             (Event.MOUSEUP | Event.MOUSEMOVE | Event.MOUSEDOWN);
  131.  
  132.     // Connect to UI //
  133.     r_slide = newSlider('ColSlider', 'rslider',
  134.                         'colorsection', 'color', 'redcell');
  135.     g_slide = newSlider('ColSlider', 'gslider',
  136.                         'colorsection', 'color', 'greencell');
  137.     b_slide = newSlider('ColSlider', 'bslider',
  138.                         'colorsection', 'color', 'bluecell');
  139.  
  140.     cpx_slide = newSlider('CPSlider', 'cpxslider',
  141.                           'campossection', 'campos', 'cpxcell');
  142.     cpy_slide = newSlider('CPSlider', 'cpyslider',
  143.                           'campossection', 'campos', 'cpycell');
  144.     cpz_slide = newSlider('CPSlider', 'cpzslider',
  145.                           'campossection', 'campos', 'cpzcell');
  146.  
  147.     cax_slide = newSlider('CASlider', 'caxslider',
  148.                           'camangsection', 'camang', 'caxcell');
  149.     cay_slide = newSlider('CASlider', 'cayslider',
  150.                           'camangsection', 'camang', 'caycell');
  151.     caz_slide = newSlider('CASlider', 'cazslider',
  152.                           'camangsection', 'camang', 'cazcell');
  153.  
  154.     lpx_slide = newSlider('LPSlider', 'lpxslider',
  155.                           'litpossection', 'litpos', 'lpxcell');
  156.     lpy_slide = newSlider('LPSlider', 'lpyslider',
  157.                           'litpossection', 'litpos', 'lpycell');
  158.     lpz_slide = newSlider('LPSlider', 'lpzslider',
  159.                           'litpossection', 'litpos', 'lpzcell');
  160.  
  161.     hncell = newCell('locsection', 'loc', 'hncell');
  162.     hURLcell = newCell('locsection', 'loc', 'hURLcell');
  163.     sURLcell = newCell('locsection', 'loc', 'sURLcell');
  164.     iURLcell = newCell('locsection', 'loc', 'iURLcell');
  165.     bgURLcell = newCell('locsection', 'loc', 'bgURLcell');
  166.     dimxcell = newCell('dimsection', 'dim', 'dimxcell');
  167.     dimycell = newCell('dimsection', 'dim', 'dimycell');
  168.     hexcell = newCell('colorsection', 'color', 'hexcell');
  169.  
  170.     // do as late as possible (we hope arthur has loaded)
  171.     aInit();
  172. }
  173.  
  174. function aInit()
  175. {
  176.     if (!ns4)
  177.         Arthur = HDoc.arthur; // HDoc.all.arthur
  178.     else if (HDoc.embeds.length)
  179.     {
  180.         // NS4BUG: ns4 seems to increment embeds.length *before* the
  181.         // embed's ready!
  182.         if (Arthur == null)
  183.             Arthur = 0;         // this is rool ugly -- delay one more time.
  184.         else
  185.             Arthur = HDoc.embeds[0];
  186.         // embeds[0] may fail noisily (and break)
  187.         // embeds['arthur'] always fails
  188.         // embeds.arthur always fails
  189.     }
  190.  
  191.     if (Arthur)
  192.         reset('all');           // set UI values
  193.     else // failed -- try again after delay (ns4 only? -- embed done late)
  194.         setTimeout("aInit()", DELAY_TM);
  195. }
  196.  
  197. // class Slider: base class for all sliders
  198. function Slider(elmt, cell)
  199. {
  200.     // this.elmt = elmt; // was dom
  201.     this.cell = cell;
  202.     this.offsetX = 0;
  203.     if (elmt)
  204.         this.initPos(elmt);
  205. }
  206. Slider.prototype.select = SlideSelect;
  207. Slider.prototype.reset = SlideReset;
  208. Slider.prototype.initPos = (ns4) ? nsInitPos : ieInitPos;
  209.  
  210. // class ColSlider: colour slider
  211. function ColSlider(dom, cell)
  212. {
  213.     this.parent(dom, cell);
  214. }
  215. ColSlider.prototype = new Slider;
  216. ColSlider.prototype.parent = Slider;
  217. ColSlider.prototype.drag = ColDrag;
  218. ColSlider.prototype.helptag = "BGColor";
  219. ColSlider.prototype.setval = ColSetVal;
  220.  
  221. // class CASlider: camera angle slider
  222. function CASlider(dom, cell)
  223. {
  224.     this.parent(dom, cell);
  225. }
  226. CASlider.prototype = new Slider;
  227. CASlider.prototype.parent = Slider;
  228. CASlider.prototype.drag = CADrag;
  229. CASlider.prototype.helptag = "CAng";
  230. CASlider.prototype.setval = CASetVal;
  231.  
  232. // class CPSlider: camera position slider
  233. function CPSlider(dom, cell)
  234. {
  235.     this.parent(dom, cell);
  236. }
  237. CPSlider.prototype = new Slider;
  238. CPSlider.prototype.parent = Slider;
  239. CPSlider.prototype.drag = CPDrag;
  240. CPSlider.prototype.helptag = "CPos";
  241. CPSlider.prototype.setval = CPSetVal;
  242.  
  243. // class LPSlider: light position slider
  244. function LPSlider(dom, cell)
  245. {
  246.     this.parent(dom, cell);
  247. }
  248. LPSlider.prototype = new Slider;
  249. LPSlider.prototype.parent = Slider;
  250. LPSlider.prototype.drag = LPDrag;
  251. LPSlider.prototype.helptag = "LPos";
  252. LPSlider.prototype.setval = LPSetVal;
  253.  
  254. // Slider method
  255. // initialise position (netscape)
  256. function nsInitPos(elmt)
  257. {
  258.     this.xpos = parseInt(elmt.left); // parseInt from "999px"
  259.     this.ypos = parseInt(elmt.top);
  260.     this.w = elmt.clip.width;
  261.     this.h = elmt.clip.height;
  262.     this.sty = elmt;
  263. }
  264.  
  265. // Slider method
  266. // initialise position (msie)
  267. function ieInitPos(elmt)
  268. {
  269.     this.xpos = elmt.offsetLeft;
  270.     this.ypos = elmt.offsetTop;
  271.     this.w = elmt.clientWidth;
  272.     this.h = elmt.clientHeight;
  273.     this.sty = elmt.style;
  274. }
  275.  
  276. function checkIdle(idleUrl)
  277. {
  278.     Idle = (idleUrl.substr(idleUrl.length - 3, 3) == "f3d");
  279.     skipButton.src = (Idle) ? SKIP_BUT : SKIP_BUT_GS;
  280.     return Idle;
  281. }
  282.  
  283. // write contents of plugin frame
  284. function makeArthur()
  285. {
  286.     var s_url1 = MOTION_URL;
  287.     var s_url2 = null;
  288.  
  289.     if (checkIdle(IDLE_URL))
  290.     {
  291.         s_url1 = IDLE_URL;
  292.         s_url2 = MOTION_URL;
  293.     }
  294.  
  295.     var dimval = new Array(WIN_DFLT, WIN_DFLT);
  296.     var cpval = new Array(0, 0, 0);
  297.     var caval = new Array(0, 0, 0);
  298.     var lpval = new Array(LPXY_DFLT, LPXY_DFLT, LPZ_DFLT);
  299.  
  300.     preview
  301.         (HDoc, "arthur", s_url1, s_url2, MODEL_URL, BG_URL, dimval, "#000000",
  302.          cpval, caval, lpval, loopcell.checked, lockcell.checked);
  303. }
  304.  
  305. // copy values into arrays
  306. function valArrays(dimval, cpval, caval, lpval)
  307. {
  308.     dimval[0] = dimxcell.value;
  309.     dimval[1] = dimycell.value;
  310.  
  311.     cpval[0] = parseFloat(cpx_slide.cell.value, 2);
  312.     cpval[1] = parseFloat(cpy_slide.cell.value, 2);
  313.     cpval[2] = parseFloat(cpz_slide.cell.value, 2);
  314.  
  315.     caval[0] = cax_slide.cell.value;
  316.     caval[1] = cay_slide.cell.value;
  317.     caval[2] = caz_slide.cell.value;
  318.  
  319.     lpval[0] = parseFloat(lpx_slide.cell.value, 1);
  320.     lpval[1] = parseFloat(lpy_slide.cell.value, 1);
  321.     lpval[2] = parseFloat(lpz_slide.cell.value, 1);
  322. }
  323.  
  324. // generate example code
  325. function process()
  326. {
  327.     // NB: can't make valArrays do "new Array" as they don't come back...
  328.     var dimval = new Array(2);
  329.     var cpval = new Array(3);
  330.     var caval = new Array(3);
  331.     var lpval = new Array(3);
  332.     valArrays(dimval, cpval, caval, lpval);
  333.  
  334.     var idle = checkIdle(iURLcell.value);
  335.     if (NeedArthurUpdate)
  336.         preview
  337.             (HDoc, "arthur", sURLcell.value, iURLcell.value, hURLcell.value,
  338.              bgURLcell.value, dimval, hexcell.value, cpval, caval, lpval,
  339.              loopcell.checked, lockcell.checked);
  340.     generate
  341.         (hncell.value, sURLcell.value, iURLcell.value, hURLcell.value,
  342.          bgURLcell.value, dimval, hexcell.value, cpval, caval, lpval,
  343.          loopcell.checked, lockcell.checked, idle);
  344.     if (NeedArthurUpdate)
  345.     {
  346.         NeedArthurUpdate = false;
  347.         // cf: aInit() re: setarthur
  348.         if (!ns4)
  349.             Arthur = HDoc.arthur;
  350.         else
  351.             Arthur = HDoc.embeds[0];
  352.     }
  353. }
  354.  
  355. // FIXME: unify: Idle, checkIdle,  url1/2, ...
  356.  
  357. // Arthur loop
  358. function toggleLoop()
  359. {
  360.     Arthur.setLooping(loopcell.checked);
  361. }
  362.  
  363. function toggleLock()
  364. {
  365.     Arthur.setLock(lockcell.checked);
  366. }
  367.  
  368. // Arthur restart
  369. function doSkip()
  370. {
  371.     if (Idle)
  372.     {
  373.         Arthur.loadUrl(MOTION_URL, true);
  374.         Arthur.loadUrl(IDLE_URL, false);
  375.     }
  376. }
  377.  
  378. // code inputs validation error
  379. function valerr(msg)
  380. {
  381.     reportErr(msg, 'Validation Error');
  382. }
  383.  
  384. function reportErr(msg, title)
  385. {
  386.     title = title || 'Error';
  387.     var doc = CDoc; // better than DDoc
  388.     doc.open(); // "text/html"
  389.     codeWrite(doc, openhtmlCode(title));
  390.     codeWrite(doc, openbodyCode(''));
  391.     doc.write('<p><font size="+1" color=red><b>', msg, '</b></font></p>');
  392.     codeWrite(doc, closehtmlCode());
  393.     doc.close();
  394. }
  395.  
  396. // check whether Java is on
  397. function checkJava()
  398. {
  399.     return navigator.javaEnabled();
  400. }
  401.  
  402. // check whether CSS is on
  403. function checkCss()
  404. {
  405.     // check whether our special "div" id is usable.
  406.     return (ns4) ? document.checkcss : checkcss;
  407. }
  408.  
  409. // validate code inputs
  410. function validate(hnval, sURLval, iURLval, hURLval, bgURLval, dimval, hexval,
  411.                   cpval, caval, lpval, loopval, lockval)
  412. {
  413.     if (!hnval)
  414.     {
  415.         valerr('The Name is invalid');
  416.         return false;
  417.     }
  418.     
  419.     if (bgURLval.length > 0 &&
  420.         (bgURLval.indexOf('.jpg') == -1 ||
  421.          (bgURLval.indexOf('http:/') == -1 &&
  422.           bgURLval.indexOf('file:/') == -1)))
  423.     {
  424.         valerr('The Backdrop URL is invalid.\n<br>' +
  425.                'NB: The viewer will only accept JPEG (.jpg) image files.');
  426.         return false;
  427.     }
  428.  
  429.     if (sURLval.indexOf(".f3d") == -1 ||
  430.         (sURLval.indexOf("http:/") == -1 &&
  431.          sURLval.indexOf("file:/") == -1))
  432.     {
  433.         valerr('The StreamURL is invalid');
  434.         return false;
  435.     }
  436.  
  437.     var test;
  438.     test = parseInt(dimval[0]);
  439.     if (test != dimval[0] || test < WIN_MIN) // never? (setDimVal)
  440.     {
  441.         valerr('The Width is invalid');
  442.         return false;
  443.     }
  444.     
  445.     test = parseInt(dimval[1]);
  446.     if (test != dimval[1] || test < WIN_MIN) // never? (setDimVal)
  447.     {
  448.         valerr('The Height is invalid');
  449.         return false;
  450.     }
  451.  
  452.     if (isNaN(cpval[0]) || isNaN(cpval[1]) || isNaN(cpval[2]))
  453.     {
  454.         valerr('The Camera Position is invalid');
  455.         return false;
  456.     }
  457.  
  458.     if (isNaN(caval[0]) || isNaN(caval[1]) || isNaN(caval[2]))
  459.     {
  460.         valerr('The Camera Angle is invalid');
  461.         return false;
  462.     }
  463.         
  464.     if (isNaN(lpval[0]) || isNaN(lpval[1]) || isNaN(lpval[2]))
  465.     {
  466.         valerr('The Light Source Position is invalid');
  467.         return false;
  468.     }
  469.  
  470.     return true;
  471. }
  472.  
  473. // code lines for: open javascript
  474. function scriptOpenCode()
  475. {
  476.     return new Array(
  477.        '<script language="javascript">',
  478.        '<!--'
  479.     );
  480. }
  481.  
  482. // code lines for: close javascript
  483. function scriptCloseCode()
  484. {
  485.     // these dangerous unbroken
  486.     return new Array(
  487.        '//--' + '>',
  488.        '<' + '/script>'
  489.     );
  490. }
  491.  
  492. // code lines for: noscript
  493. function noscriptCode()
  494. {
  495.     // this isn't very helpful...
  496.     return new Array(
  497.         '<noscript>',
  498.         '<h1>JavaScript is required for this page.</h1>',
  499.         '</noscript>'
  500.     );
  501. }
  502.  
  503. // code lines for: examples
  504. function idleEgCode(sURL, iURL)
  505. {
  506.     return new Array
  507.         ('<' + '!-- an example button --' + '>',
  508.          '<a href="javascript:reloadF3D',
  509.          '  (\'' + sURL + '\',',
  510.          '   \'' + iURL + '\')"',
  511.          '  >Click Here</a>');
  512.     // 'document.' + hnval + '.loadUrl("sURL", "interrupt");'
  513. }
  514.  
  515. function idleCodeComments(hnval)
  516. {
  517.     return new Array
  518.         ('<p>The following code should be put in the <head> section',
  519.          'of the HTML document that contains the stream.</p>',
  520.  
  521.          '<p><i>reloadF3D()</i> resets the stream playlist, and puts',
  522.          'the two streams (sURL, iURL) in the playlist.  Also, the last',
  523.          'stream in the playlist will loop until interrupted.</p>',
  524.  
  525.          '<p><i>loadUrl()</i> is part of the famous3D viewer API.',
  526.          'eg: document.' + hnval + '.loadUrl("sURL", "interrupt");</p>',
  527.  
  528.          '<p><i>' + hnval + '</i> should be the name specified in the',
  529.          '<object> tag\'s "ID" parameter, and/or the',
  530.          '<embed> tag\'s "name" parameter.</p>',
  531.  
  532.          '<p><i>sURL</i> (string) should be an absolute URL for the motion',
  533.          'stream to be loaded.</p>',
  534.  
  535.          '<p><i>interrupt</i> (boolean) if true will stop playing the',
  536.          'current stream, empty the playlist, and start playing the new',
  537.          'stream immediately.  If false, the viewer will add the stream to',
  538.          'the end of the playlist.</p>');
  539. }
  540.  
  541. function idleCode(hnval)
  542. {
  543.     return new Array
  544.         ('function reloadF3D(sURL, iURL)',
  545.          '{',
  546.          '    document.' + hnval + '.loadUrl(sURL, true);',
  547.          '    document.' + hnval + '.loadUrl(iURL, false);',
  548.          '    document.' + hnval + '.setLooping(true);',
  549.          '}');
  550. }
  551.  
  552. // write code example to window for main/idle stream combo
  553. function genIdleCode(hnval, sURLval, iURLval)
  554. {
  555.     CDoc.writeln('<p><b>Javascript for Multiple Streams</b></p>');
  556.  
  557.     // comments
  558.     // NS4BUG: <table> convinces ns4 not to keep on applying div colour.
  559.     CDoc.writeln('<table cellspacing=0 cellpadding=0 border=0><tr><td>');
  560.     CDoc.writeln('<div style="color:blue;">');
  561.     codeWrite(CDoc, idleCodeComments(hnval));
  562.     CDoc.writeln('</td></tr></table></div>');
  563.  
  564.     // code
  565.     CDoc.writeln('<pre>');
  566.     codeEscWrite(CDoc, scriptOpenCode(), '');
  567.     codeEscWrite(CDoc, idleCode(hnval), '  ');
  568.     codeEscWrite(CDoc, scriptCloseCode(), '');
  569.     codeEscWrite(CDoc, idleEgCode(sURLval, iURLval), '');
  570.     CDoc.writeln('</pre>');
  571. }
  572.  
  573. // generate the contents of the example code window
  574. function generate(hnval, sURLval, iURLval, hURLval, bgURLval, dimval, hexval,
  575.                   cpval, caval, lpval, loopval, lockval, idle)
  576. {
  577.     if (!validate(hnval, sURLval, iURLval, hURLval, bgURLval, dimval, hexval,
  578.                   cpval, caval, lpval, loopval, lockval))
  579.         return;                  
  580.  
  581.     source = (idle) ? iURLval : sURLval;
  582.  
  583.     CDoc.open();
  584.     codeWrite(CDoc, openhtmlCode(''));
  585.     codeWrite(CDoc, openbodyCode(''));
  586.  
  587.     if (idle)
  588.     {
  589.        genIdleCode(hnval, sURLval, iURLval);
  590.        CDoc.writeln('<hr>');
  591.     }
  592.  
  593.     // comments
  594.     CDoc.writeln('<p><b>Javascript for embedding a stream</b></p>');
  595.     CDoc.writeln('<p><font color=blue>The following code should be put in ',
  596.                  'the <body> section of your web page.</font></p>');
  597.  
  598.     // start code
  599.     CDoc.writeln('<p><pre>');
  600.     codeEscWrite(CDoc, scriptOpenCode(), '');
  601.  
  602.     CDoc.writeln('bName = navigator.appName;');
  603.     CDoc.writeln('bVer = parseInt(navigator.appVersion);');
  604.     CDoc.writeln('hasPlugin = (navigator.plugins["Famous3D viewer"]) ? ',
  605.                  'true : false;');
  606.     CDoc.writeln('');
  607.     CDoc.writeln('document.open();');
  608.     CDoc.writeln('if (bName == "Microsoft Internet Explorer")');
  609.     CDoc.writeln('{');
  610.     CDoc.writeln('    if ((navigator.platform.indexOf("Win") != -1) &&');
  611.     CDoc.writeln('        (navigator.platform.indexOf("Win16") == -1))');
  612.     CDoc.writeln('    {');
  613.  
  614.     var code;
  615.     code = ieViewCode(hnval, sURLval, hURLval, bgURLval, dimval, hexval,
  616.                       cpval, caval, lpval, loopval, lockval);
  617.     codeDocWrite(CDoc, code, '        ');
  618.  
  619.     CDoc.writeln('    }');
  620.     CDoc.writeln('    else');
  621.     CDoc.writeln('    {');
  622.  
  623.     code = badPlatformCode();
  624.     codeDocWrite(CDoc, code, '        ');
  625.  
  626.     CDoc.writeln('    }');
  627.     CDoc.writeln('}');
  628.     CDoc.writeln('else if (bName == "Netscape")');
  629.     CDoc.writeln('{');
  630.     CDoc.writeln('    if (hasPlugin)');
  631.     CDoc.writeln('    {');
  632.         
  633.     code = nsViewCode(hnval, sURLval, hURLval, bgURLval, dimval, hexval,
  634.                       cpval, caval, lpval, loopval, lockval);
  635.     codeDocWrite(CDoc, code, '        ');
  636.  
  637.     CDoc.writeln('    }');
  638.     CDoc.writeln('    else');
  639.     CDoc.writeln('    {');
  640.     codeDocWrite(CDoc, dlPluginCode(dimval), '        ');
  641.     CDoc.writeln('    }');
  642.     CDoc.writeln('}');
  643.     CDoc.writeln('else');
  644.     CDoc.writeln('{');
  645.  
  646.     code = badBrowserCode();
  647.     codeDocWrite(CDoc, code, '    ');
  648.  
  649.     CDoc.writeln('}');
  650.     CDoc.writeln('document.close();');
  651.     codeEscWrite(CDoc, scriptCloseCode(), '');
  652.     CDoc.writeln('</pre></p>');
  653.  
  654.     // noscript (comments)
  655.     CDoc.writeln('<p><font color=blue>This is used if the user does not ',
  656.                  'have Javascript enabled in the browser. ',
  657.                  'Put a version of your site that does not use Javascript ',
  658.                  'here.</font></p>');
  659.  
  660.     // noscript (code)
  661.     CDoc.writeln('<pre>');
  662.     codeEscWrite(CDoc, noscriptCode(), '');
  663.     CDoc.writeln('</pre>');
  664.  
  665.     // last comment
  666.     CDoc.writeln('<p><font color=blue>For further assistance contact ',
  667.                  '<a href="mailto:support@famous3d.com">',
  668.                  'support@famous3d.com</a></font></p>');
  669.  
  670.     codeWrite(CDoc, closehtmlCode(''));
  671.     CDoc.close();
  672. }
  673.  
  674. // code lines for: open html
  675. // nb: leaves trailing head... (cf openbodyCode)
  676. function openhtmlCode(title)
  677. {
  678.     // some of these tags too dangerous to leave unbroken
  679.     return new Array(
  680.         '<' + 'html>',
  681.         '<' + 'head>',
  682.         '<title>' + title + '</title>'
  683.     );
  684. }
  685.  
  686. // code lines for: open body
  687. // nb: closes head, opens body (cf openhtml, closehtml)
  688. function openbodyCode(bodyargs)
  689. {
  690.     // some of these tags too dangerous to leave unbroken
  691.     return new Array(
  692.         '<' + '/head>',
  693.         '<' + 'body ' + bodyargs + '>'
  694.     );
  695. }
  696.  
  697. // code lines for: close html (and body: cf openhtml, openbody)
  698. function closehtmlCode()
  699. {
  700.     return new Array(
  701.         '<' + '/body>',
  702.         '<' + '/html>'
  703.     );
  704. };
  705.  
  706. // generate our local page
  707. function preview(doc, hnval, s_url1, s_url2, hURLval, bgURLval, dimval, hexval,
  708.                  cpval, caval, lpval, loopval, lockval)
  709. {
  710.     doc.open();
  711.     codeWrite(doc, openhtmlCode(''));
  712.     codeWrite(doc, openbodyCode(''));
  713.     doc.writeln('<center>');
  714.     var success = pluginPage(doc, hnval, s_url1, hURLval, bgURLval, dimval,
  715.                              hexval, cpval, caval, lpval, loopval, lockval,
  716.                              'false');
  717.     doc.writeln('</center>');
  718.  
  719.     codeWrite(doc, closehtmlCode());
  720.     doc.close();
  721. }
  722.  
  723. // generate a plugin page
  724. function pluginPage(doc, hnval, s_url, hURLval, bgURLval, dimval, hexval,
  725.                     cpval, caval, lpval, loopval, lockval, pause)
  726. {
  727.     bName = navigator.appName; 
  728.     bVer = parseInt(navigator.appVersion); 
  729.     var success = true;
  730.     var code;
  731.     if (bName == "Microsoft Internet Explorer") 
  732.     {
  733.         if (navigator.platform.indexOf("Win") != -1 &&
  734.             navigator.platform.indexOf("Win16") == -1)
  735.         {
  736.             code = ieViewCode("arthur", s_url, hURLval, bgURLval, dimval,
  737.                               hexval, cpval, caval, lpval, loopval, lockval,
  738.                               pause);
  739.         }
  740.         else
  741.         {
  742.             code = badPlatformCode();
  743.             success = false;
  744.         }
  745.     } 
  746.     else if (bName == "Netscape")
  747.     {
  748.         code = nsViewCode("arthur", s_url, hURLval, bgURLval, dimval, hexval,
  749.                           cpval, caval, lpval, loopval, lockval, pause);
  750.     }
  751.     else
  752.     {
  753.         success = false;
  754.         code = badBrowserCode();
  755.     }
  756.     codeWrite(doc, code);
  757.     return success;
  758. }
  759.  
  760. // write lines of code (directly)
  761. function codeWrite(doc, code)
  762. {
  763.     // 'join' is faster than iteration (?)
  764.     doc.writeln(code.join('\n'));
  765. }
  766.  
  767. // escape a line for writing 
  768. function escapeStr(line)
  769. {
  770.     // String.replace hopefully cheaper than us iterating over string
  771.     var newline = line.replace(/</g, '<');
  772.     newline =  newline.replace(/>/g, '>');
  773.     return newline;
  774. }
  775.  
  776. // write lines of document.write() code
  777. function codeDocWrite(doc, code, indent)
  778. {
  779.     // 'join' is faster than iteration (?)
  780.     var joinstr = CDW_CLOSE + indent + CDW_OPEN;
  781.     codeDocWriteLine(doc, code.join(joinstr), indent);
  782. }
  783.  
  784. // write escaped lines of code
  785. function codeEscWrite(doc, code, indent)
  786. {
  787.     if (!indent)
  788.         indent = '';
  789.     // 'join' is faster than iteration (?)
  790.     codeEscWriteLine(doc, code.join('\n' + indent), indent);
  791. }
  792.  
  793. // write a 'document.write(code)' line to doc (with indent)
  794. function codeDocWriteLine(doc, line, indent)
  795. {
  796.     doc.write(indent, CDW_OPEN, escapeStr(line), CDW_CLOSE);
  797. }
  798.  
  799. // write an escaped line of code to doc
  800. function codeEscWriteLine(doc, line, indent)
  801. {
  802.     if (!indent)
  803.         indent = '';
  804.     doc.writeln(indent, escapeStr(line));
  805. }
  806.  
  807. // code lines for: plugin under msie
  808. function
  809. ieViewCode(hnval, sURLval, hURLval, bgURLval, dimval, hexval, cpval, caval,
  810.            lpval, loopval, lockval, pause)
  811. {
  812.     pause = pause || 'false';
  813.     return new Array
  814.         ('<table width=' + dimval[0] + ' height=' + dimval[1] +
  815.              ' cellpadding=0 cellspacing=0>', // bgcolor="#ffffff"
  816.          '<tr valign=top><td width=0>', // 0 width -> good "installing" align 
  817.          // div style:"background-color:#ffffff;"
  818.          '<div id="ielayer1" style="position:absolute; z-index:1;">',
  819.          '<object id="' + hnval + '"',
  820.          '  classid="CLSID:' + CLASSID + '"',
  821.          '  codebase="' + CODEBASE + '"',
  822.          '  width=' + dimval[0] + ' height=' + dimval[1] + '>',
  823.          '<param name="bgcolor" value="' + hexval + '">',
  824.          '<param name="streamURL" value="' + sURLval + '">',
  825.          '<param name="headURL" value="' + hURLval + '">',
  826.          '<param name="bgTextureURL" value="' + bgURLval + '">',
  827.          '<param name="cameraPosition" value="' +
  828.              cpval[0] + ' ' + cpval[1] + ' ' + cpval[2] + '">',
  829.          '<param name="cameraRotation" value="' +
  830.              caval[0] + ' ' + caval[1] + ' ' + caval[2] + '">',
  831.          '<param name="lightPosition" value="' +
  832.              lpval[0] + ' ' + lpval[1] + ' ' + lpval[2] + '">',
  833.          '<param name="loop" value="' + loopval + '">',
  834.          '<param name="cameraLock" value=' + lockval + '">',
  835.          '<param name="pause" value="' + pause + '">',
  836.          '',
  837.          '<table cellpadding=5><tr><td>', // bgcolor="#ffffff"
  838.          LOGO_IMG_TAG,
  839.          '<font ' + FONT_VALS + '>',
  840.          '<br>The famous3D viewer failed to install.',
  841.          '<br><br>Refresh the page if you wish to retry installing, or',
  842.          // a color="#0000ff"
  843.          '<a href="' + ABOUT_LINK + '" target="_blank">click here</a>',
  844.          'to find out more about the famous3D Viewer</font>',
  845.          '</td></tr></table>',
  846.          '</object>',
  847.          '</div></td>',
  848.          '',
  849.          // NB: this code simply sits *behind* the plugin...
  850.          // FIXME: this code will break w/out CSS... 
  851.          '<td>' + INSTALL_IMG_TAG,
  852.          '<font ' + FONT_VALS + '>',
  853.          '<br>Installing Famous3D Viewer',
  854.          '<br>Please Wait...</font>',
  855.          '</td></tr>',
  856.          '</table>');
  857. }
  858.  
  859. // code lines for: bad platform
  860. function badPlatformCode()
  861. {
  862.     return new Array
  863.         ('<div align="center">',
  864.          LOGO_IMG_TAG,
  865.          '<font ' + FONT_VALS + '>',
  866.          '<br>The famous3D Viewer only works on the Windows platform.',
  867.          'Sorry.</font>',
  868.          '</div>');
  869. }
  870.  
  871. // code lines for: download plugin
  872. function dlPluginCode(dimval)
  873. {
  874.     return new Array
  875.         // bgcolor="#0000ad" width=300 height=300
  876.         ('<table width=' + dimval[0] + ' height=' + dimval[1] + '>',
  877.          '<tr valign=middle><td align=center>',
  878.          '<a href="' + PLUGINSPAGE + '" target="_blank">',
  879.          LOGO_IMG_TAG,
  880.          '</a></td></tr></table>');
  881. }
  882.  
  883. // code lines for: plugin under netscape
  884. function
  885. nsViewCode(hnval, sURLval, hURLval, bgURLval, dimval, hexval, cpval, caval,
  886.            lpval, loopval, lockval, pause)
  887. {
  888.     pause = pause || 'false';
  889.     return new Array
  890.         ('<embed src="' + sURLval + '"',
  891.          '  width=' + dimval[0] + ' height=' + dimval[1],
  892.          '  name="' + hnval + '"',
  893.          '  pluginspage="' + PLUGINSPAGE + '"',
  894.          '  bgcolor="' + hexval + '"',
  895.          '  headURL="' + hURLval + '"',
  896.          '  bgTextureURL="' + bgURLval + '"',
  897.          '  loop="' + loopval + '"',
  898.          '  cameraLock="' + lockval + '"',
  899.          '  pause="' + pause + '"',
  900.          '  cameraPosition="' + cpval[0] +' '+ cpval[1] +' '+ cpval[2] + '"',
  901.          '  cameraRotation="' + caval[0] +' '+ caval[1] +' '+ caval[2] + '"',
  902.          '  lightPosition="'  + lpval[0] +' '+ lpval[1] +' '+ lpval[2] + '">',
  903.          '</embed>');
  904. }
  905.  
  906. // code lines for: bad browser
  907. function badBrowserCode()
  908. {
  909.     return new Array
  910.         ('<p align="center">',
  911.          LOGO_IMG_TAG,
  912.          '<font ' + FONT_VALS + '>',
  913.          '<br>This site requires the use of Microsoft Internet Explorer 4.0',
  914.          'or above; or Netscape Navigator 4.0 or above',
  915.          '(excluding Netscape 6.0).',
  916.          '<br>Please use one of these browsers to view famous3D animations...',
  917.          'or download them.</font></p>',
  918.          '<ul>',
  919.          '  <li><font ' + FONT_VALS + '>',
  920.          '<a href="' + NS_LINK + '">Click here</a>',
  921.          '  to get the latest version of Netscape Navigator.</font></li>',
  922.          '  <li><font ' + FONT_VALS + '>' +
  923.          '<a href="' + IE_LINK + '">Click here</a>',
  924.          '  to get the latest version of',
  925.          '  Microsoft Internet Explorer.</font></li>',
  926.          '</ul>');
  927. }
  928.  
  929. // Slide method
  930. function SlideSelect(x, y)
  931. {
  932.     if (x > this.xpos && x < this.xpos + this.w &&
  933.         y > this.ypos && y < this.ypos + this.h)
  934.     {
  935.         helpme(this.helptag);
  936.         return this;
  937.     }
  938.     return null;
  939. }
  940.  
  941. // selection
  942. function selectObject(e)
  943. {
  944.     var x = (ns4) ? e.pageX : (event.x + document.body.scrollLeft);
  945.     var y = (ns4) ? e.pageY : (event.y + document.body.scrollTop);
  946.  
  947.     SelectedSlide = 
  948.         r_slide.select(x, y) ||
  949.         g_slide.select(x, y) ||
  950.         b_slide.select(x, y) ||
  951.  
  952.         cpx_slide.select(x, y) ||
  953.         cpy_slide.select(x, y) ||
  954.         cpz_slide.select(x, y) ||
  955.  
  956.         cax_slide.select(x, y) ||
  957.         cay_slide.select(x, y) ||
  958.         caz_slide.select(x, y) ||
  959.         
  960.         lpx_slide.select(x, y) ||
  961.         lpy_slide.select(x, y) ||
  962.         lpz_slide.select(x, y);
  963.  
  964.     if (SelectedSlide)
  965.     {
  966.         document.onmousemove = dragObject;
  967.         document.onmouseup = freeObject;
  968.         SelectedSlide.offsetX = x - SelectedSlide.xpos;
  969.     }
  970. }
  971.  
  972. // drag slider
  973. function dragVal(e, slide)
  974. {
  975.     var x = (ns4) ? e.pageX : (event.x + document.body.scrollLeft);
  976.     var MoveToX = x - slide.offsetX;
  977.     if (MoveToX < S_HMIN)
  978.         MoveToX = S_HMIN;
  979.     if (MoveToX > S_HMAX)
  980.         MoveToX = S_HMAX;
  981.  
  982.     slide.xpos = MoveToX;
  983.     slide.sty.left = MoveToX;
  984. }
  985.  
  986. // Slider method
  987. function ColDrag(e)
  988. {
  989.     dragVal(e, this);
  990.     refreshColorCells();
  991. }
  992.  
  993. // Slider method
  994. function CPDrag(e)
  995. {
  996.     dragVal(e, this);
  997.     var val = CP_MIN + (CP_RANGE * (this.xpos - S_HMIN) / SRANGE);
  998.     this.cell.value = format(val, 2);
  999.     moveCamPos();
  1000. }
  1001.  
  1002. // Slider method
  1003. function CADrag(e)
  1004. {
  1005.     dragVal(e, this);
  1006.     var val = CA_MIN + (CA_RANGE * (this.xpos - S_HMIN) / SRANGE);
  1007.     val = parseInt(val);
  1008.     if (isNaN(val))
  1009.        val = 0;
  1010.     this.cell.value = val;
  1011.     moveCamAng();
  1012. }
  1013.  
  1014. // Slider method
  1015. function LPDrag(e)
  1016. {
  1017.     dragVal(e, this);
  1018.     var val = LP_MIN + (LP_RANGE * (this.xpos - S_HMIN) / SRANGE);
  1019.     this.cell.value = format(val, 1);
  1020.     moveLightPos();
  1021. }
  1022.  
  1023. // drag slider
  1024. function dragObject(e)
  1025. {
  1026.     if (SelectedSlide)
  1027.         SelectedSlide.drag(e);
  1028. }
  1029.  
  1030. // update hex, plugin from colour sliders
  1031. function refreshColorCells()
  1032. {
  1033.     // Colour Cells
  1034.     var red = r_slide.xpos - S_HMIN;
  1035.     var green = g_slide.xpos - S_HMIN;
  1036.     var blue = b_slide.xpos - S_HMIN;
  1037.     
  1038.     r_slide.cell.value = red;
  1039.     g_slide.cell.value = green;
  1040.     b_slide.cell.value = blue;
  1041.  
  1042.     var hexred = red.toString(16);
  1043.     var hexgreen = green.toString(16);
  1044.     var hexblue = blue.toString(16);
  1045.  
  1046.     if (hexred.length == 1)
  1047.         hexred = "0" + hexred;
  1048.     if (hexgreen.length == 1)
  1049.         hexgreen = "0" + hexgreen;
  1050.     if (hexblue.length == 1)
  1051.         hexblue = "0" + hexblue;
  1052.  
  1053.     hexcode = "#" + hexred + hexgreen + hexblue;
  1054.     hexcell.value = hexcode.toUpperCase();
  1055.     
  1056.     if (ns4)
  1057.         document.colorproof.bgColor = hexcode;
  1058.     else
  1059.         colorproof.style.backgroundColor = hexcode;
  1060.  
  1061.     Arthur.setBgColorHex(hexcode);
  1062. }
  1063.  
  1064. // update slider from value
  1065. function setOffset(slider, offset)
  1066. {
  1067.     if (offset < 0 || isNaN(offset))
  1068.         offset = 0;
  1069.     if (offset > SRANGE)
  1070.         offset = SRANGE;
  1071.     offset += S_HMIN;
  1072.     slider.xpos = offset;
  1073.     slider.sty.left = offset;
  1074. }
  1075.  
  1076. // Slider method
  1077. function ColSetVal(value, noupdate)
  1078. {
  1079.     var offset = parseInt(value);
  1080.     setOffset(this, offset);
  1081.     if (!noupdate)
  1082.         refreshColorCells();
  1083. }
  1084.  
  1085. // Slider method
  1086. function CPSetVal(value, noupdate)
  1087. {
  1088.     var offset = SRANGE * (parseFloat(value) - CP_MIN) / CP_RANGE;
  1089.     setOffset(this, offset);
  1090.     if (!noupdate)
  1091.         moveCamPos();
  1092. }
  1093.  
  1094. // Slider method
  1095. function CASetVal(value, noupdate)
  1096. {
  1097.     var offset = SRANGE * (parseInt(value) - CA_MIN) / CA_RANGE;
  1098.     setOffset(this, offset);
  1099.     if (!noupdate)
  1100.         moveCamAng();
  1101. }
  1102.  
  1103. // Slider method
  1104. function LPSetVal(value, noupdate)
  1105. {
  1106.     var offset = SRANGE * (parseFloat(value) - LP_MIN) / LP_RANGE;
  1107.     setOffset(this, offset);
  1108.     if (!noupdate)
  1109.         moveLightPos();
  1110. }
  1111.     
  1112. function setDimVal(cell)
  1113. {
  1114.     var value = parseInt(cell.value);
  1115.     if (isNaN(value))
  1116.         cell.value = WIN_DFLT;
  1117.     else if (value < WIN_MIN)
  1118.         cell.value = WIN_MIN;
  1119.     else if (value > WIN_MAX)
  1120.         cell.value = WIN_MAX;
  1121.     else
  1122.         cell.value = value;
  1123.  
  1124.     if (cell.oldval != cell.value)
  1125.     {
  1126.         NeedArthurUpdate = true;
  1127.         cell.oldval = cell.value;
  1128.     }
  1129. }
  1130.  
  1131. function setUrlVal(cell)
  1132. {
  1133.     var value = cell.value;
  1134.  
  1135. //      var i = value.length - 1;
  1136. //      for ( ; value.charAt(i) != "/" && i > 0; i--)
  1137. //          ;
  1138. //      hURLcell.value = value.substr(0, i);
  1139. //      if (cell == iURLcell)
  1140. //          iURLcell.value = value.substr(0, i);
  1141.  
  1142.     if (cell.oldval != cell.value)
  1143.     {
  1144.         NeedArthurUpdate = true;
  1145.         cell.oldval = cell.value;
  1146.     }
  1147. }
  1148.     
  1149. function setHexVal(cell)
  1150. {
  1151.     var value = cell.value;
  1152.  
  1153.     if (value.length == 6 && value.substr(0, 1) != "#")
  1154.     { 
  1155.         value = "#" + value;
  1156.         cell.value = value;
  1157.     }
  1158.         
  1159.     if (value.length > 7) 
  1160.     {
  1161.         value = "#000000";
  1162.         cell.value = value;
  1163.     }
  1164.  
  1165.     var hexred = value.substr(1, 2);
  1166.     var hexgreen = value.substr(3, 2);
  1167.     var hexblue = value.substr(5, 2);
  1168.  
  1169.     red = parseInt(hexred, 16);
  1170.     green = parseInt(hexgreen, 16);
  1171.     blue = parseInt(hexblue, 16);
  1172.         
  1173.     if (isNaN(red))
  1174.     {
  1175.         red = 0;
  1176.         value = "00" + value.substr(3, 4);
  1177.         cell.value = value;
  1178.     }
  1179.         
  1180.     if (isNaN(green))
  1181.     {
  1182.         green = 0;
  1183.         value = value.substr(0, 2) + "00" + value.substr(5, 2);
  1184.         cell.value = value;
  1185.     }
  1186.     
  1187.     if (isNaN(blue))
  1188.     {
  1189.         blue = 0;
  1190.         value = value.substr(0, 4) + "00";
  1191.         cell.value = value;
  1192.     }
  1193.  
  1194.     setOffset(r_slide, red);
  1195.     setOffset(g_slide, green);
  1196.     setOffset(b_slide, blue);
  1197.         
  1198.     refreshColorCells();
  1199. }
  1200.  
  1201. // update plugin from UI
  1202. function moveCamPos()
  1203. {
  1204.     var fx = parseFloat(cpx_slide.cell.value);
  1205.     var fy = parseFloat(cpy_slide.cell.value);
  1206.     var fz = parseFloat(cpz_slide.cell.value);
  1207.     Arthur.setCameraPosition(fx, fy, fz);
  1208. }
  1209.  
  1210. // update plugin from UI
  1211. function moveCamAng()
  1212. {
  1213.     var fx = parseFloat(cax_slide.cell.value);
  1214.     var fy = parseFloat(cay_slide.cell.value);
  1215.     var fz = parseFloat(caz_slide.cell.value);
  1216.     Arthur.setCameraRotation(fx, fy, fz);
  1217. }
  1218.  
  1219. // update plugin from UI
  1220. function moveLightPos()
  1221. {
  1222.     var fx = parseFloat(lpx_slide.cell.value);
  1223.     var fy = parseFloat(lpy_slide.cell.value);
  1224.     var fz = parseFloat(lpz_slide.cell.value);
  1225.     Arthur.setLightPosition(fx, fy, fz);
  1226. }
  1227.  
  1228. // done interaction
  1229. function freeObject(e)
  1230. {
  1231.     document.onmousemove = null;
  1232.     document.onmouseup = null;
  1233.     SelectedSlide = null;
  1234. }
  1235.  
  1236. // generate truncated floating point string
  1237. function format(value, fp)
  1238. {
  1239.     var pow = Math.pow(10, fp);
  1240.     return Math.round(value * pow) / pow;
  1241. }
  1242.  
  1243. // Slide method
  1244. function SlideReset(val)
  1245. {
  1246.     this.setval(val, 1); // set value with no update
  1247.     this.cell.value = val;
  1248. }
  1249.  
  1250. // reset values to defaults
  1251. function reset(section)
  1252. {
  1253.     if (section == "loc" || section == "all")
  1254.     {
  1255.         hncell.value = MODEL_NAME;
  1256.         sURLcell.value = MOTION_URL;
  1257.         iURLcell.value = IDLE_URL;
  1258.         hURLcell.value = MODEL_URL;
  1259.         bgURLcell.value = BG_URL;
  1260.     }
  1261.     
  1262.     if (section == "dim" || section == "all")
  1263.     {
  1264.         dimxcell.value = WIN_DFLT;
  1265.         dimycell.value = WIN_DFLT;
  1266.     }
  1267.  
  1268.     if (section == "color" || section == "all")
  1269.     {
  1270.         r_slide.reset(0);
  1271.         g_slide.reset(0);
  1272.         b_slide.reset(0);
  1273.         refreshColorCells(); // takes care of hex, too!
  1274.     }
  1275.  
  1276.     if (section == "campos" || section == "all")
  1277.     {
  1278.         cpx_slide.reset(0);
  1279.         cpy_slide.reset(0);
  1280.         cpz_slide.reset(0);
  1281.         moveCamPos();
  1282.     }
  1283.  
  1284.     if (section == "camang" || section == "all")
  1285.     {
  1286.         cax_slide.reset(0);
  1287.         cay_slide.reset(0);
  1288.         caz_slide.reset(0);
  1289.         moveCamAng();
  1290.     }
  1291.  
  1292.     if (section == "litpos" || section == "all")
  1293.     {
  1294.         lpx_slide.reset(LPXY_DFLT);
  1295.         lpy_slide.reset(LPXY_DFLT);
  1296.         lpz_slide.reset(LPZ_DFLT);
  1297.         moveLightPos();
  1298.     }
  1299. }
  1300.  
  1301. // help text for UI
  1302. function helpme(help_index)
  1303. {
  1304.     if (PrevHelp == help_index)
  1305.         return;
  1306.     PrevHelp = help_index;
  1307.  
  1308.     var title = null;
  1309.     var msg = null;
  1310.     if (help_index == "name")
  1311.     {
  1312.         title = 'Name';
  1313.         msg = '\t The name refers to the name of the object so that it ' +
  1314.         'can be referenced to by your javascript.\n<br><br>' +
  1315.         '\t It is recommended that this variable has a meaningful name ' +
  1316.         'such as the name of your character.';
  1317.     }
  1318.     if (help_index == "streamURL")
  1319.     {
  1320.         title = 'StreamURL (Motion URL)';
  1321.         msg = '\t StreamURL is the absolute path to your stream eg ' +
  1322.         'http://www.arthur.com/streams/arthur.f3d';
  1323.     }
  1324.     if (help_index == "idleURL")
  1325.     {
  1326.         title = 'IdleURL';    
  1327.         msg = '\t idleURL is the absolute path to your idle stream. ' +
  1328.         'The idle stream will be looped at the begining and the end of ' +
  1329.         'the main stream (specified above).  There is additional code ' +
  1330.         'added for a button to activate the main stream and play the ' +
  1331.         'idle stream once it is complete.';
  1332.     }
  1333.     if (help_index == "headURL")
  1334.     {
  1335.         title = 'HeadURL (Model URL)';
  1336.         msg = '\t headURL is the absolute path to your head model, ' +
  1337.         'usually this is the directory where your streams are being ' +
  1338.         'stored eg http://www.arthur.com/streams';
  1339.     }
  1340.     if (help_index == "bgURL")
  1341.     {
  1342.         title = 'Background Texture URL';
  1343.         msg = '\t bgURL is the absolute path of a JPEG (.jpg) texture ' +
  1344.             'to be used as a background image in the viewer.';
  1345.     }
  1346.     if (help_index == "Dim")
  1347.     {
  1348.         title = 'Dimension';
  1349.         msg = '\t Enter the height and width that you wish your head ' +
  1350.         'to be. The standard size is about ' + WIN_DFLT + 'x' + WIN_DFLT +
  1351.         ' pixels.';
  1352.     }
  1353.     if (help_index == "BGColor")
  1354.     {
  1355.         title = 'Background Colour';
  1356.         msg = '\t You can use the sliders to get a colour.  You can ' +
  1357.         'also enter the Red Green and Blue (0 - 255) values in the ' +
  1358.         'boxes along side the sliders or enter a Hex value in the box ' +
  1359.         '(#000000 - #FFFFFF) and finetune the colour with the sliders.';
  1360.     }
  1361.     if (help_index == "CPos")
  1362.     {
  1363.         title = 'Camera Position';
  1364.         msg = '\t Use the sliders to move the head around or specify a ' +
  1365.         'unit in the fields above the sliders.<br> The edges of the box ' +
  1366.         'are between +/- 1.  The allowed range is between +/- ' + CP_MAX +
  1367.         ' units.';
  1368.     }
  1369.     if (help_index == "CAng")
  1370.     {
  1371.         title = 'Camera Angle';
  1372.         msg = '\t The Camera angle is Specified in Degrees around each ' +
  1373.         'axis, You can use the sliders to adjust this value or specify ' +
  1374.         'values in the boxes above the sliders. The allowed range is ' +
  1375.         'between +/- ' + CA_MAX + ' degrees.';
  1376.     }
  1377.     if (help_index == "LPos")
  1378.     {
  1379.         title = 'Light Source Position';
  1380.         msg = '\t Lighting Position is a lot like Camera Position. The ' +
  1381.         'allowed range for values is +/- ' + LP_MAX + ' units.';
  1382.     }
  1383.     if (help_index == "gen")
  1384.     {
  1385.         title = 'The Script';
  1386.         msg = '\t Now you can cut and paste the generated script into ' +
  1387.         'your page and make minor adjustments. The script will detect ' +
  1388.         'whether the user has the plugin and automatically or direct ' +
  1389.         'them to a site where they can install the plugin.';
  1390.     }
  1391.  
  1392.     if (title)
  1393.     {
  1394.         DDoc.open();
  1395.         codeWrite(DDoc, openhtmlCode(title));
  1396.         codeWrite(DDoc, openbodyCode(''));
  1397.         DDoc.writeln('<b>', title, '</b>');
  1398.         DDoc.writeln('<table cellspacing=0 cellpadding=3>');
  1399.         DDoc.writeln('<tr><td>', msg, '</td></tr>');
  1400.         DDoc.writeln('</table>');
  1401.         codeWrite(DDoc, closehtmlCode());
  1402.         DDoc.close();
  1403.     }
  1404. }
  1405.  
  1406. function fullCellName(section, form, cellname)
  1407. {
  1408.     if (ns4)
  1409.         return 'document.' + section + '.document.' + form + '.' + cellname;
  1410.     else
  1411.         return form + "." + cellname; 
  1412. }
  1413.  
  1414. function newCell(section, form, cellname)
  1415. {
  1416.     // NB: eval() can crash early NS -- test?
  1417.     return eval(fullCellName(section, form, cellname));
  1418. }
  1419.  
  1420. function newSlider(sliderType, sliderName, section, form, cellname)
  1421. {
  1422.     fullslidername = (ns4) ? 'document.' + sliderName : sliderName;
  1423.     // NB: eval() can crash early NS -- test?
  1424.     return eval('new ' + sliderType + '(' + fullslidername + ', ' +
  1425.                 fullCellName(section, form, cellname) + ');');
  1426. }
  1427.